home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / osk_asy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-09  |  8.4 KB  |  425 lines

  1. /* OS- and machine-dependent stuff for asynch ports on OS-9
  2.  * Copyright 1993 Brian A. Lantz, KO4KS
  3.  */
  4. #include <stdio.h>
  5. #include <dos.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "mbuf.h"
  9. #include "proc.h"
  10. #include "iface.h"
  11. #include "i8250.h"
  12. #include "asy.h"
  13. #include "devparam.h"
  14. #include "pc.h"
  15. #include <sgstat.h>
  16. #include <modes.h>
  17.  
  18. extern int _gs_opt();
  19. extern void _ss_opt();
  20.  
  21. #define ASY_MAX 5
  22. #define PARAM_SPEED 10
  23.  
  24. static void asy_tx __ARGS((int dev,void *p1,void *p2));
  25.  
  26. struct asy Asy[ASY_MAX];
  27.  
  28. /* Initialize asynch port "dev" */
  29. int
  30. asy_init(dev,ifp,arg1,arg2,bufsize,trigchar,monitor,speed,force,triglevel)
  31. int dev;
  32. struct iface *ifp;
  33. char *arg1,*arg2;    /* Attach args for address and vector */
  34. int16 bufsize;
  35. int trigchar;
  36. char monitor;
  37. long speed;
  38. int force;
  39. int triglevel;
  40. {
  41. register unsigned base;
  42. register struct fifo *fp;
  43. register struct asy *ap;
  44. char termname[8], prefix[4];
  45. char *ifn;
  46. struct sgbuf sbuf;
  47. short *nm = (short *) prefix;
  48.         
  49.         ap = &Asy[dev];
  50.         ap->iface = ifp;
  51.  
  52.     ap->addr = atoi(arg2);   /* hex string for device name prefix */
  53.     *nm = htoi(arg1);   /* hex-coded ASCII for name prefix "t" etc */
  54.     if (!prefix[0])
  55.         prefix[0] = 't';
  56.  
  57.     /* Set up receiver FIFO */
  58.     fp = &ap->fifo;
  59.     fp->buf = mallocw(bufsize);
  60.     fp->bufsize = bufsize;
  61.     fp->wp = fp->rp = fp->buf;
  62.     fp->cnt = 0;
  63.     fp->hiwat = 0;
  64.     fp->overrun = 0;
  65.     base = ap->addr;
  66.     ap->trigchar = trigchar;
  67.  
  68.         sprintf (termname, "/%s%d", prefix, base);
  69.         if ((ap->vec = (unsigned) fopen(termname, "a+")) == 0) {
  70.             tprintf("asy%d: Open failed.\n", dev);
  71.             return -1;
  72.         }
  73.         setbuf ((FILE *) ap->vec, NULL);
  74.     asy_speed(dev,speed);
  75.  
  76.         _gs_opt(fileno((FILE *)ap->vec), &sbuf);
  77.         sbuf.sg_case = 0;
  78.         sbuf.sg_backsp = 0;
  79.         sbuf.sg_delete = 0;
  80.         sbuf.sg_echo = 0;
  81.         sbuf.sg_alf = 0;
  82. /*        sbuf.sg_nulls = 0;    */
  83.         sbuf.sg_pause = 0;
  84.         sbuf.sg_page = 0;
  85.         sbuf.sg_bspch = 0;
  86.         sbuf.sg_dlnch = 0;
  87.         sbuf.sg_eorch = 0;
  88.         sbuf.sg_eofch = 0;
  89.         sbuf.sg_rlnch = 0;
  90.         sbuf.sg_dulnch = 0;
  91.         sbuf.sg_psch = 0;
  92.         sbuf.sg_kbich = 0;
  93.         sbuf.sg_kbach = 0;
  94.         sbuf.sg_bsech = 0;
  95.         sbuf.sg_bellch = 0;
  96.         sbuf.sg_xon = 0;
  97.         sbuf.sg_xoff = 0;
  98. /*        sbuf.sg_tabcr = 0;
  99.         sbuf.sg_tabsiz = 0;    */
  100.         _ss_opt(fileno((FILE *)ap->vec), &sbuf);
  101.  
  102.     ifp->txproc = newproc( ifn = if_name(ifp," tx"),
  103.             256, asy_tx, dev, ifp, NULL, 0);
  104.     free(ifn);
  105.  
  106.         return 0;
  107. }
  108.  
  109.  
  110. int
  111. asy_stop(ifp)
  112. struct iface *ifp;
  113. {
  114.     register unsigned base;
  115.     register struct asy *ap;
  116.  
  117.     ap = &Asy[ifp->dev];
  118.     free(ap->fifo.buf);
  119.     fclose ((FILE *)ap->vec);
  120.     ap->vec = 0;
  121.     return 0;
  122. }
  123.  
  124.  
  125. /* Asynchronous line I/O control */
  126. int32
  127. asy_ioctl(ifp,cmd,set,val)
  128. struct iface *ifp;
  129. int cmd;
  130. int set;
  131. int32 val;
  132. {
  133. struct asy *ap = &Asy[ifp->dev];
  134. int16 base = ap->addr;
  135.  
  136.     switch(cmd){
  137.     case PARAM_SPEED:
  138.         if(set)
  139.             asy_speed(ifp->dev,val);
  140.         return ap->speed;
  141. #ifdef notyet
  142.     case PARAM_DTR:
  143.         if(set) {
  144.             writebit(base+MCR,MCR_DTR,(int)val);
  145.             ap->dtr_usage = (val) ? MOVED_UP : MOVED_DOWN;
  146.         }
  147.         return (inportb(base+MCR) & MCR_DTR) ? TRUE : FALSE;
  148.     case PARAM_RTS:
  149.         if(set) {
  150.             writebit(base+MCR,MCR_RTS,(int)val);
  151.             ap->rts_usage = (val) ? MOVED_UP : MOVED_DOWN;
  152.         }
  153.         return (inportb(base+MCR) & MCR_RTS) ? TRUE : FALSE;
  154.     case PARAM_DOWN:
  155.         clrbit(base+IER,(char)IER_DAV);
  156.         clrbit(base+MCR,MCR_RTS);
  157.         clrbit(base+MCR,MCR_DTR);
  158.         ap->rts_usage = MOVED_DOWN;
  159.         ap->dtr_usage = MOVED_DOWN;
  160.         return FALSE;
  161.     case PARAM_UP:
  162.         setbit(base+IER,(char)IER_DAV);
  163.         setbit(base+MCR,MCR_RTS);
  164.         setbit(base+MCR,MCR_DTR);
  165.         ap->rts_usage = MOVED_UP;
  166.         ap->dtr_usage = MOVED_UP;
  167.         return TRUE;
  168.     case PARAM_BLIND:
  169.         setbit(base+IER,(char)IER_DAV);
  170.         ap->rlsd_line_control = IGNORED;
  171.  
  172.         if ( ap->monitor != NULL ) {
  173.             killproc( ap->monitor );
  174.             ap->monitor = NULL;
  175.         }
  176.  
  177.         /* can't see what we are doing, so pretend we're up */
  178.         if ( ifp->iostatus != NULL ) {
  179.             (*ifp->iostatus)(ifp, PARAM_UP, 0L);
  180.         }
  181.         return TRUE;
  182. #endif
  183.     };
  184.     return -1;
  185. }
  186.  
  187.  
  188. /* Set asynch line speed */
  189. int
  190. asy_speed(dev,speed)
  191. int dev;
  192. long speed;
  193. {
  194.     return 0;
  195. }
  196.  
  197.  
  198. /* Start transmission of a buffer on the serial transmitter */
  199. static void
  200. asy_output(dev,buf,cnt)
  201. int dev;
  202. char *buf;
  203. unsigned short cnt;
  204. {
  205. struct asy *asyp;
  206.  
  207.     if(dev < 0 || dev >= ASY_MAX)
  208.         return;
  209.     asyp = &Asy[dev];
  210.     if(asyp->iface == NULLIF)
  211.         return;
  212.     asyp->txints++;
  213.     asyp->txchar += cnt;
  214.     fwrite (buf, 1, cnt, (FILE *)asyp->vec);
  215. }
  216.  
  217.  
  218. /* Blocking read from asynch line
  219.  * Returns character or -1 if aborting
  220.  * Returns -2 (CD_DOWN) if carrier checking is on and dropped
  221.  */
  222. int
  223. get_asy(dev)
  224. int dev;
  225. {
  226. char i_state;
  227. register struct fifo *fp;
  228. char c;
  229.  
  230.     fp = &Asy[dev].fifo;
  231.  
  232.     while(fp->cnt == 0){
  233.         if(pwait(fp) != 0)
  234.             return -1;
  235.     }
  236.     fp->cnt--;
  237.  
  238.     c = *fp->rp++;
  239.     if(fp->rp >= &fp->buf[fp->bufsize])
  240.         fp->rp = fp->buf;
  241.  
  242.     return uchar(c);
  243. }
  244.  
  245. /* Process received characters */
  246. static int
  247. asyrxint(asyp)
  248. struct asy *asyp;
  249. {
  250. register struct fifo *fp;
  251. char c,lsr;
  252. int cnt = 0, doneone = 0;
  253. int trigseen = FALSE;
  254.  
  255.     if (!asyp->vec)
  256.         return cnt;
  257.     fp = &asyp->fifo;
  258.     for(;;){
  259.         if(_gs_rdy(fileno((FILE *)asyp->vec)) > 0){
  260.             asyp->rxchar++;
  261.             doneone = 1;
  262.             fread (&c, 1, 1, (FILE *)asyp->vec);
  263.             if(asyp->trigchar == uchar(c))
  264.                 trigseen = TRUE;
  265.             /* If buffer is full, we have no choice but
  266.              * to drop the character
  267.              */
  268.             if(fp->cnt != fp->bufsize){
  269.                 *fp->wp++ = c;
  270.                 if(fp->wp >= &fp->buf[fp->bufsize])
  271.                     /* Wrap around */
  272.                     fp->wp = fp->buf;
  273.                 fp->cnt++;
  274.                 if(fp->cnt > fp->hiwat)
  275.                     fp->hiwat = fp->cnt;
  276.                 cnt++;
  277.             } else
  278.                 fp->overrun++;
  279.         } else
  280.             break;
  281.     }
  282.     if(cnt > asyp->rxhiwat)
  283.         asyp->rxhiwat = cnt;
  284.     if(trigseen)
  285.         psignal(fp,1);
  286.     if (doneone)
  287.         asyp->rxints++;
  288.     return cnt;
  289. }
  290.  
  291.  
  292. /* Poll the asynch input queues; called on every clock tick.
  293.  * This helps limit the interrupt ring buffer occupancy when long
  294.  * packets are being received.
  295.  */
  296. void
  297. asytimer()
  298. {
  299. register struct asy *asyp;
  300. register struct fifo *fp;
  301. register int i;
  302.  
  303.     for(i=0;i<ASY_MAX;i++){
  304.         asyp = &Asy[i];
  305.         asyrxint (asyp);
  306.         fp = &asyp->fifo;
  307.         if(fp->cnt != 0)
  308.             psignal(fp,1);
  309. #ifdef notyet TIPMAIL
  310.         if (Tipsuspended[i].ifp)    {
  311.             if (!carrier_detect(i))    {
  312.                 char buf[40];
  313.                 sprintf (buf, "start tip %s %s %d\n", Tipsuspended[i].ifp->name, (Tipsuspended[i].modem) ? "m" : "t", Tipsuspended[i].timeout);
  314.                 cmdparse(Cmds,buf,NULL);
  315.                 Tipsuspended[i].ifp = 0;
  316.                 Tipsuspended[i].modem = 0;
  317.                 Tipsuspended[i].timeout = 0;
  318.             }
  319.         }
  320. #endif
  321.     }
  322. }
  323.  
  324.  
  325. int
  326. doasystat(argc,argv,p)
  327. int argc;
  328. char *argv[];
  329. void *p;
  330. {
  331. register struct asy *asyp;
  332.  
  333.     for(asyp = Asy;asyp < &Asy[ASY_MAX];asyp++){
  334.         if(asyp->iface == NULLIF)
  335.             continue;
  336.  
  337.         tprintf("%s:",asyp->iface->name);
  338.         if(asyp->trigchar != -1)
  339.             tprintf(" [trigger 0x%02x]",asyp->trigchar);
  340. #ifdef notyet
  341.         switch (asyp->cts_flow_control) {
  342.         case MOVED_DOWN:
  343.         case MOVED_UP:
  344.             tprintf(" [cts flow control]");
  345.             break;
  346.         };
  347.         switch (asyp->rlsd_line_control) {
  348.         case MOVED_DOWN:
  349.         case MOVED_UP:
  350.             tprintf(" [rlsd line control]");
  351.             break;
  352.         case IGNORED:
  353.             tprintf(" [blind]");
  354.             break;
  355.         };
  356. #endif
  357.         tprintf(" %lu bps\n",asyp->speed);
  358.  
  359.         tprintf(" RX: %lu int, %lu chr, %lu hw over, %lu hw hi\n",
  360.             asyp->rxints,
  361.             asyp->rxchar,
  362.             asyp->overrun,
  363.             asyp->rxhiwat);
  364.         asyp->rxhiwat = 0;
  365.         if(tprintf(" TX: %lu int, %lu chars, %u q\n",
  366.             asyp->txints, asyp->txchar, len_q(asyp->sndq)) == EOF)
  367.             break;
  368.     }
  369.     return 0;
  370. }
  371.  
  372.  
  373. /* Send a message on the specified serial line */
  374. int
  375. asy_send(dev,bp)
  376. int dev;
  377. struct mbuf *bp;
  378. {
  379.     if(dev < 0 || dev >= ASY_MAX)
  380.         return -1;
  381.     enqueue(&Asy[dev].sndq,bp);
  382.     return 0;
  383. }
  384.  
  385.  
  386.  
  387. /* Serial transmit process, common to all protocols */
  388. static void
  389. asy_tx(dev,p1,p2)
  390. int dev;
  391. void *p1;
  392. void *p2;
  393. {
  394. register struct mbuf *bp;
  395. struct asy *asyp;
  396.  
  397.     asyp = &Asy[dev];
  398.  
  399.     for(;;){
  400.         /* Fetch a buffer for transmission */
  401.         while(asyp->sndq == NULLBUF)
  402.             pwait(&asyp->sndq);
  403.  
  404.         bp = dequeue(&asyp->sndq);
  405.  
  406.         while(bp != NULLBUF){
  407.             /* Start the transmitter */
  408.             asy_output(dev,bp->data,bp->cnt);
  409.  
  410.             /* Now do next buffer on chain */
  411.             bp = free_mbuf(bp);
  412.         }
  413.     }
  414. }
  415.  
  416.  
  417. int
  418. carrier_detect(dev)
  419. int dev;
  420. {
  421.     return 1;
  422. }
  423.  
  424.  
  425.